home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / term.exe / TERM.CPP < prev    next >
C/C++ Source or Header  |  1992-01-07  |  17KB  |  586 lines

  1. //    Author: Patrick Reilly
  2. //    ID:        70274,161 (Compuserve)
  3. //    Version    1.01
  4.  
  5. //    Contents --------------------------------------------------------------
  6. //
  7. //      termbuf::termbuf                        constructor
  8. //        termbuf::~termbuf                        destructor
  9. //        termbuf::setbuf
  10. //      termbuf::underflow
  11. //      termbuf::overflow
  12. //        termbuf::setmap
  13. //        termbuf::setWindow
  14. //        termbuf::setBackground
  15. //        termbuf::setForeground
  16. //        termbuf::setAttribute
  17. //        termbuf::clearWindow
  18. //        termbuf::gotoWindow
  19. //      termbuf::initScreen
  20. //      termbuf::processKey
  21. //
  22. //  Description
  23. //
  24. //      Class termbuf is derived from streambuf for use in terminal
  25. //    emulation (for telecommunication apps). The key to emulation is
  26. //    mapping keystrokes (scan+ascii) to both actions and terminal
  27. //    emulation strings. termbuf class does this with the typedef structure
  28. //    KeyMap. Certain keystrokes are hardcoded to certain actions
  29. //    (ie ascii 30h prints the letter '0' and ^PGDN clears the screen). In
  30. //    the KeyMap structure they are then cross-referenced to the emulation
  31. //    string for that keycode. For example, the keycode 0x5000 (DOWN key) is
  32. //    hardcoded to move the cursor down one line, and (in VT102 emulation)
  33. //    softcoded to "\x01B[B". Therefore if you extract the keystroke 'down-
  34. //    arrow' you will extract the string "\x01B[B", and if you insert the
  35. //    string "\x01B[B" the cursor will move down the screen one row.
  36. //
  37. //    End ------------------------------------------------------------------
  38.  
  39. //    Interface Dependencies -----------------------------------------------
  40.  
  41. #ifndef __TERM_H
  42. #include "term.h"
  43. #endif
  44.  
  45. #ifndef __BIOS_H
  46. #include <bios.h>
  47. #endif
  48.  
  49. #ifndef __CTYPE_H
  50. #include <ctype.h>
  51. #endif
  52.  
  53. #ifndef __STRING_H
  54. #include <string.h>
  55. #endif
  56.  
  57. //    End Interface Dependencies --------------------------------------------
  58.  
  59. //    Constructor //
  60.  
  61. _Cdecl termbuf::termbuf()
  62.  
  63. //    Summary --------------------------------------------------------------
  64. //
  65. //        Constructor for class termbuf.
  66. //
  67. //    Functional Description
  68. //
  69. //        The two constructors for termbuf are identical. It sets the base
  70. //    streambuf class buffer pointers to NULL so that all incoming and out-
  71. //    going characters will be forced to call member underflow() and
  72. //    overflow(). It sets the key mapping pointers to NULL to indicate that
  73. //    no emulation is in effect. It initializes emapbuf to the end of the
  74. //    input buffer (mapbuf)+1 and the input put pointer (pmap) to the start
  75. //    of the buffer. It fills the mapMatch array with ones to indicate that
  76. //    no elements of the KeyMap array have been eliminated by earlier
  77. //    entries. It initializes the text_info structure to the current screen
  78. //    window, cursor location, and attribute.
  79. //
  80. //    End -------------------------------------------------------------------
  81.  
  82.     {
  83.     setb(0,0);        setp(0,0);        setg(0,0,0);    // clear pointers.
  84.     map = emap = 0;
  85.     insLen = keymapsize = 0;
  86.     gettextinfo(&ti);
  87.     }
  88.  
  89. //    End Constructor //
  90.  
  91. //    Constructor //
  92.  
  93. _Cdecl termbuf::termbuf(char _FAR *,int)
  94.  
  95. //    Summary --------------------------------------------------------------
  96. //
  97. //        Constructor for class termbuf.
  98. //
  99. //    Functional Description
  100. //
  101. //        The two constructors for termbuf are identical. It sets the base
  102. //    streambuf class buffer pointers to NULL so that all incoming and out-
  103. //    going characters will be forced to call member underflow() and
  104. //    overflow(). It sets the key mapping pointers to NULL to indicate that
  105. //    no emulation is in effect. It initializes emapbuf to the end of the
  106. //    input buffer (mapbuf)+1 and the input put pointer (pmap) to the start
  107. //    of the buffer. It fills the mapMatch array with ones to indicate that
  108. //    no elements of the KeyMap array have been eliminated by earlier
  109. //    entries. It initializes the text_info structure to the current screen
  110. //    window, cursor location, and attribute.
  111. //
  112. //    End -------------------------------------------------------------------
  113.  
  114.     {
  115.     setb(0,0);        setp(0,0);        setg(0,0,0);
  116.     map = emap = 0;
  117.     insLen = keymapsize = 0;
  118.     gettextinfo(&ti);
  119.     }
  120.  
  121. //    End Constructor //
  122.  
  123. //    Destructor //
  124. _Cdecl termbuf::~termbuf()
  125.  
  126. //    Summary --------------------------------------------------------------
  127. //
  128. //        Vanilla destructor.
  129. //
  130. //    End ------------------------------------------------------------------
  131.  
  132.     {
  133.     }
  134.  
  135. //    Member Function //
  136.  
  137. streambuf _FAR * _Cdecl termbuf::setbuf(signed char _FAR *,int)
  138.  
  139. //    Summary --------------------------------------------------------------
  140. //
  141. //        Overloaded base member.
  142. //
  143. //    Functional Description
  144. //
  145. //        This member is overloaded because a streambuf buffer is not
  146. //    maintained in the conventional manner.
  147. //
  148. //    End ------------------------------------------------------------------
  149.  
  150.     {
  151.     return this;
  152.     }
  153.  
  154. //    End Member Function //
  155.  
  156. //    Member Function //
  157.  
  158. int _Cdecl termbuf::underflow()
  159.  
  160. //    Summary --------------------------------------------------------------
  161. //
  162. //        Overloaded member called when extraction fails.
  163. //
  164. //    Functional Description
  165. //
  166. //      Extraction takes place under one of two conditions: 1) the streambuf
  167. //    'get' buffer is empty and you need to get a character from the keyboard,
  168. //    or 2) you previously extracted from the keyboard an are getting
  169. //    subsequent chars from a multi-character emulation (ie one keystroke
  170. //    equates to 2+ emulation chars). If underflow() is called with the get
  171. //    buffer empty, it will call bioskey(0) to wait for a keystroke response
  172. //    from the user. It then searches the KeyMap array for a matching entry.
  173. //    If one is not found, it loops back for another key. If a match is found,
  174. //    the streambuf get pointers are set to the emulation string that
  175. //    corresponds to that keystroke. This way, subsequent extraction will
  176. //    read all of the emulation string before underflow() is called again.
  177. //        If the KeyMap pointer is NULL (no emulation), each keystroke is
  178. //    returned with no translation.
  179. //
  180. //    End ------------------------------------------------------------------
  181.  
  182.     {
  183.     char *p,*e;
  184.     int x,lo,hi,i;
  185.  
  186.     if(!map)            // no emulation
  187.         {
  188.         setb(&noMap,&noMap+1);
  189.         setg(&noMap,&noMap,&noMap+1);
  190.         noMap = bioskey(0) & 0xFF;
  191.         return (int)noMap;
  192.         }
  193.  
  194.     while(1)
  195.         {
  196.         x = bioskey(0);
  197.  
  198.         // perform binary search for keycode //
  199.         for(lo = 0,hi = keymapsize-1; lo != hi;)
  200.             {
  201.             i = lo+(hi-lo)/2;
  202.             if(map[i].keycode == x)    break;
  203.             else if(map[i].keycode < x)    lo = i;
  204.             else                        hi = i;
  205.             }
  206.         if(map[i].keycode == x)    break;
  207.         }
  208.     p = map[i].string;
  209.     for(e = p; *e; e++);
  210.  
  211.     // set the get and buffer pointers to the emulation string //
  212.     setb(p,e);
  213.     setg(p,p,e);
  214.     return *p;
  215.     }
  216.  
  217. //    End Member Function //
  218.  
  219. //    Member Function //
  220.  
  221. int _Cdecl termbuf::overflow(int ch)
  222.  
  223. //    Summary --------------------------------------------------------------
  224. //
  225. //        Overloaded insertion member.
  226. //
  227. //    Functional Description
  228. //
  229. //      Since the streambuf 'put' pointers are maintained at NULL, all
  230. //    insertion will cause overflow() to be called for each character. There
  231. //    are two cases overflow() must handle: emulation is in effect (the KeyMap
  232. //    pointer member map is not NULL) or it is not in effect.
  233. //        Class termbuf maintains a member mapMatch, which is just an array
  234. //    of flags that correspond to each KeyMap element. When a character is
  235. //    inserted, overflow() searches all of the KeyMap emulation strings for
  236. //    a match. If an element does not match, the corresponding mapMatch flag
  237. //    is set to false. If a match IS found and the next character in the
  238. //    emulation string is a NULL (end of string), the emulation has been
  239. //    completed and processKey() member is called for the corresponding
  240. //    keycode and the member returns. If there was no match in any of the
  241. //    emulation strings (all elements of mapMatch false), then the insertion
  242. //    was unrecognizable and everything is reinitialized.
  243. //        If no emulation is in effect (KeyMap pointer member map is NULL), the
  244. //    character inserted is sent to processKey().
  245. //
  246. //    NOTE:
  247. //
  248. //        Please note that insertion emulation is performed as follows: an
  249. //    inserted string is correlated to a keycode in the